// This is the main DLL file.

#include "stdafx.h"
#include <new>

#include "NxCoreConnector.h"

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Globalization;

namespace Tradex {
	namespace Connectivity {
		namespace NxCore {

			NxCoreConnector::NxCoreConnector () {
			};

			NxCoreConnector::~NxCoreConnector () {
				Disconnect ();
			};

			// IConnector - start

			void NxCoreConnector::SetCallback(IConnectorCallback^ callback) {
				if (callback == nullptr) {
					pConnectorCallback = callback;
					return;
				}
				if (pConnectorCallback != nullptr) {
					throw gcnew InvalidOperationException ("Connector Callback already registered");
				}
				pConnectorCallback = callback;
			}

			void NxCoreConnector::Connect (String^ connectionString) {
				OnStatusUpdate (ConnectionStatusCode::Connecting, nullptr);

				DbConnectionStringBuilder^ pConnectionStringBuilder = gcnew DbConnectionStringBuilder ();
				pConnectionStringBuilder->ConnectionString = connectionString;

				System::Object^ out;
				pConnectionStringBuilder->TryGetValue ("Tape", out);
				String^ tape = (String^) out;

				char* pTape = nullptr;
				if (tape!= nullptr) {
					pTape = (char*)(void*) Marshal::StringToHGlobalAnsi(tape);
				}

				pNative = new NativeConnector(this);
				pNative->Connect (pTape);

				if (pTape != nullptr) {
					Marshal::FreeHGlobal(IntPtr(pTape));
				}
			}

			void NxCoreConnector::Disconnect () {
				if (pNative != nullptr) {
					pNative->Disconnect ();
					delete pNative;
					pNative = nullptr;
				}
			}
				
			bool NxCoreConnector::IsConnected::get () {
				return pNative != nullptr;
			}

			void NxCoreConnector::OnLogEntry (
				System::Diagnostics::TraceLevel traceLevel,
				String^ subject,
				String^ message,
				String^ origin,
				String^ reference
			) {
				if (pConnectorCallback != nullptr) {
					pConnectorCallback->LogEntry (traceLevel, subject, message, origin, reference);
				}
			}

			void NxCoreConnector::OnStatusUpdate (
				ConnectionStatusCode code,
				String^ message
			) {
				if (pConnectorCallback != nullptr) {
					pConnectorCallback->StatusUpdate (code, message);
				}
			}

			// IConnector - end

			// IMarketConnector - start

			void NxCoreConnector::SetCallback(IMarketConnectorCallback^ callback) {
				if (callback == nullptr) {
					pMarketConnectorCallback = callback;
					return;
				}
				if (pMarketConnectorCallback != nullptr) {
					throw gcnew InvalidOperationException ("MarketConnector Callback already registered");
				}
				pMarketConnectorCallback = callback;
			}

			[System::Security::SecurityCritical()]
			void NxCoreConnector::Subscribe (InstrumentKey^ instrument, ActivityFilters filter) {
			}

			[System::Security::SecurityCritical()]
			void NxCoreConnector::Subscribe (MarketKey^ market, ActivityFilters filter) {
			}

			[System::Security::SecurityCritical()]
			void NxCoreConnector::GetReferenceData (InstrumentKey^ instrument) {
			}

			void NxCoreConnector::OnActivity (InstrumentKey^ instrument, Activity^ activity) {
				if (pMarketConnectorCallback != nullptr) {
					pMarketConnectorCallback->Activity (instrument, activity);
				}
			}

			void NxCoreConnector::OnReferenceUpdate (InstrumentKey^ instrument, InstrumentInfo^ instrumentInfo, InstrumentPricing^ instrumentPricing) {
				if (pMarketConnectorCallback != nullptr) {
					pMarketConnectorCallback->InstrumentUpdate (instrument, instrumentInfo, instrumentPricing);
				}
			}

			// IMarketConnector - end

		}
	}
}